home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / OpenGL / OPENGL2.EXE / _SETUP.1 / fullscreen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-31  |  8.2 KB  |  321 lines

  1. /* 
  2.  
  3.    fullscreen.c
  4.    Nate Robins, 1997.
  5.  
  6.    An example of rendering OpenGL fullscreen using Win32.  Use the
  7.    mouse to select a mode.  Modes that are highlighted in green are
  8.    modes that can be changed to dynamically.  Those in red can't be
  9.    changed to dynamically (they require a reboot).  If you change to a
  10.    mode that has the wrong refresh rate, you can press the right mouse
  11.    button which will take you to the default display mode.  The mode
  12.    that is highlighted in yellow is the current display mode.  Press
  13.    'Esc' to quit.  The program returns to the defalt display mode on
  14.    exit.
  15.    
  16.  */
  17.  
  18. #include <windows.h>
  19. #include <GL/glut.h>
  20. #include <stdio.h>
  21.  
  22. HDC hDC;
  23. int win_width, win_height;
  24. int row = 0, col = 0;
  25. int num_modes = 0;
  26. int row_size = 10, col_size = 0;
  27. int num_cols = 3, num_rows = 0;
  28. int current = -1;
  29. int cant = 0;
  30. DEVMODE devmode;
  31. DEVMODE *devmodes;
  32.  
  33.  
  34. /* 
  35.  
  36.    general purpose text routine.  draws a string according to the
  37.    format in a stroke font at x, y after scaling it by the scale
  38.    specified.  x, y and scale are all in window-space [i.e., pixels]
  39.    with origin at the lower-left.
  40.  
  41.  */
  42.  
  43. void 
  44. text(GLuint x, GLuint y, GLuint scale, char* format, ...)
  45. {
  46.     va_list args;
  47.     char buffer[255], *p;
  48.     GLfloat font_scale = 119.05F + 33.33F;
  49.  
  50.     va_start(args, format);
  51.     vsprintf(buffer, format, args);
  52.     va_end(args);
  53.  
  54.     glMatrixMode(GL_PROJECTION);
  55.     glPushMatrix();
  56.     glLoadIdentity();
  57.     gluOrtho2D(0, win_width, 0, win_height);
  58.  
  59.     glMatrixMode(GL_MODELVIEW);
  60.     glPushMatrix();
  61.     glLoadIdentity();
  62.  
  63.     glPushAttrib(GL_ENABLE_BIT);
  64.     glDisable(GL_LIGHTING);
  65.     glDisable(GL_TEXTURE_2D);
  66.     glDisable(GL_DEPTH_TEST);
  67.     glTranslatef((GLfloat) x, (GLfloat) y, 0.0F);
  68.  
  69.     glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
  70.  
  71.     for(p = buffer; *p; p++)
  72.     glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, *p);
  73.   
  74.     glPopAttrib();
  75.  
  76.     glPopMatrix();
  77.     glMatrixMode(GL_PROJECTION);
  78.     glPopMatrix();
  79.     glMatrixMode(GL_MODELVIEW);
  80. }
  81.  
  82. void
  83. display()
  84. {
  85.     int i, x, y;
  86.  
  87.     glViewport(0, 0, win_width, win_height);
  88.     glMatrixMode(GL_PROJECTION);
  89.     glLoadIdentity();
  90.     gluOrtho2D(0, win_width, 0, win_height);
  91.     glMatrixMode(GL_MODELVIEW);
  92.     glLoadIdentity();
  93.     glPolygonMode(GL_FRONT, GL_LINE);
  94.     glClear(GL_COLOR_BUFFER_BIT);
  95.  
  96.     for (i = 0; i < num_modes; i++) {
  97.     x = i / num_rows * col_size;
  98.     y = i % num_rows * row_size;
  99.  
  100.     glColor3f(1.0F, 1.0F, 1.0F);
  101.     if (current == i)
  102.         glColor3f(1.0F, 1.0F, 0.0F);
  103.     if (row*row_size == y && col*col_size == x) {
  104.         /* test to see if the mode that the mouse pointer is above
  105.                is dynamic. */
  106.         if (ChangeDisplaySettings(&devmodes[i], CDS_TEST) ==
  107.         DISP_CHANGE_SUCCESSFUL) {
  108.         glColor3f(0.0F, 1.0F, 0.0F);
  109.         } else {
  110.         glColor3f(1.0F, 0.0F, 0.0F);
  111.         }
  112.         /* draw a box around the current choice. */
  113.         glRecti(x, y-2, x+col_size, y+row_size-1);
  114.     }
  115.     text(x, y, row_size, "%3d: %4dx%4d %2d bps %3dhz\n", i,
  116.          devmodes[i].dmPelsWidth, devmodes[i].dmPelsHeight, 
  117.          devmodes[i].dmBitsPerPel, devmodes[i].dmDisplayFrequency);
  118.     }
  119.  
  120.     /* let the user know that they can't choose that one.  "cant"
  121.        decrements so that a few frames of the message are seen
  122.        (otherwise it blinks off too quickly to read). */
  123.     if (cant) {
  124.     glColor3f(1.0F, 0.0F, 0.0F);
  125.     text(0, win_height-20, 20, "Can't dynamically resize to that format.");
  126.     cant--;
  127.     }
  128.  
  129.     glFlush();
  130.     SwapBuffers(hDC);
  131. }
  132.  
  133.  
  134. LONG WINAPI
  135. WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  136.     int i;
  137.     static PAINTSTRUCT ps;
  138.  
  139.     switch(uMsg) {
  140.     case WM_PAINT:
  141.     display();
  142.     BeginPaint(hWnd, &ps);
  143.     EndPaint(hWnd, &ps);
  144.     return 0;
  145.  
  146.     case WM_SIZE:
  147.           win_width = LOWORD(lParam);
  148.     win_height = HIWORD(lParam);
  149.     num_rows = win_height / row_size;
  150.     col_size = win_width / num_cols;
  151.     PostMessage(hWnd, WM_PAINT, 0, 0);
  152.     return 0;
  153.  
  154.     case WM_CHAR:
  155.     switch (wParam) {
  156.     case 27:            /* ESC key */
  157.         PostQuitMessage(0);
  158.         break;
  159.     }
  160.     return 0;
  161.  
  162.     case WM_LBUTTONDOWN:
  163.     i = col * num_rows + row;
  164.     if (i < num_modes) {
  165.         /* test first, then change, just in case. */
  166.         if (ChangeDisplaySettings(&devmodes[i], CDS_TEST) == 
  167.         DISP_CHANGE_SUCCESSFUL)
  168.         {
  169.         ChangeDisplaySettings(&devmodes[i], 0);
  170.         current = i;
  171.         } else {
  172.         cant = 5;
  173.         PostMessage(hWnd, WM_PAINT, 0, 0);
  174.         }
  175.     }
  176.     return 0;
  177.  
  178.     case WM_RBUTTONDOWN:
  179.     /* click your heels three times...hang on toto. */
  180.     ChangeDisplaySettings(NULL, 0);
  181.     return 0;
  182.  
  183.     case WM_MOUSEMOVE:
  184.     col = LOWORD(lParam) / col_size;
  185.     row = (win_height - HIWORD(lParam)) / row_size;
  186.     PostMessage(hWnd, WM_PAINT, 0, 0);
  187.     return 0;
  188.  
  189.     case WM_CLOSE:
  190.     PostQuitMessage(0);
  191.     return 0;
  192.     }
  193.  
  194.     return DefWindowProc(hWnd, uMsg, wParam, lParam); 
  195.  
  196. HWND
  197. CreateOpenGLWindow(char* title, int x, int y, int width, int height, 
  198.            BYTE type, DWORD flags)
  199. {
  200.     int         pf;
  201.     HDC         hDC;
  202.     HWND        hWnd;
  203.     WNDCLASS    wc;
  204.     PIXELFORMATDESCRIPTOR pfd;
  205.     static HINSTANCE hInstance = 0;
  206.  
  207.     /* only register the window class once - use hInstance as a flag. */
  208.     if (!hInstance) {
  209.     hInstance = GetModuleHandle(NULL);
  210.     wc.style         = CS_OWNDC;
  211.     wc.lpfnWndProc   = (WNDPROC)WindowProc;
  212.     wc.cbClsExtra    = 0;
  213.     wc.cbWndExtra    = 0;
  214.     wc.hInstance     = hInstance;
  215.     wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
  216.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  217.     wc.hbrBackground = NULL;
  218.     wc.lpszMenuName  = NULL;
  219.     wc.lpszClassName = "OpenGL";
  220.  
  221.     if (!RegisterClass(&wc)) {
  222.         MessageBox(NULL, "RegisterClass() failed:  "
  223.                "Cannot register window class.", "Error", MB_OK);
  224.         return NULL;
  225.     }
  226.     }
  227.  
  228.     hWnd = CreateWindow("OpenGL", title, WS_POPUP | WS_MAXIMIZE |
  229.             WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
  230.             x, y, width, height, NULL, NULL, hInstance, NULL);
  231.  
  232.     if (hWnd == NULL) {
  233.     MessageBox(NULL, "CreateWindow() failed:  Cannot create a window.",
  234.            "Error", MB_OK);
  235.     return NULL;
  236.     }
  237.  
  238.     hDC = GetDC(hWnd);
  239.  
  240.     /* there is no guarantee that the contents of the stack that become
  241.        the pfd are zeroed, therefore _make sure_ to clear these bits. */
  242.     memset(&pfd, 0, sizeof(pfd));
  243.     pfd.nSize        = sizeof(pfd);
  244.     pfd.nVersion     = 1;
  245.     pfd.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
  246.     pfd.iPixelType   = type;
  247.     pfd.cColorBits   = 32;
  248.  
  249.     pf = ChoosePixelFormat(hDC, &pfd);
  250.     if (pf == 0) {
  251.     MessageBox(NULL, "ChoosePixelFormat() failed:  "
  252.            "Cannot find a suitable pixel format.", "Error", MB_OK); 
  253.     return 0;
  254.     } 
  255.  
  256.     if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
  257.     MessageBox(NULL, "SetPixelFormat() failed:  "
  258.            "Cannot set format specified.", "Error", MB_OK);
  259.     return 0;
  260.     } 
  261.  
  262.     DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  263.  
  264.     ReleaseDC(hDC, hWnd);
  265.  
  266.     return hWnd;
  267. }    
  268.  
  269. int APIENTRY
  270. WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
  271.     LPSTR lpszCmdLine, int nCmdShow)
  272. {
  273.     HGLRC hRC;                /* opengl context */
  274.     HWND hWnd;                /* window */
  275.     MSG msg;                /* message */
  276.  
  277.     hWnd = CreateOpenGLWindow("minimal", 0, 0, win_width, win_height,
  278.                   PFD_TYPE_RGBA, PFD_DOUBLEBUFFER);
  279.     if (hWnd == NULL)
  280.     exit(1);
  281.  
  282.     hDC = GetDC(hWnd);
  283.     hRC = wglCreateContext(hDC);
  284.     wglMakeCurrent(hDC, hRC);
  285.  
  286.     ShowWindow(hWnd, SW_SHOW);
  287.  
  288.     /* get the total number of modes so we can allocate memory for all
  289.        of 'em. */
  290.     num_modes = 0;
  291.     while (EnumDisplaySettings(NULL, num_modes, &devmode))
  292.     num_modes++;
  293.  
  294.     /* fill an array with all the devmodes so we don't have to keep
  295.        grabbing 'em. */
  296.     devmodes = (DEVMODE*)malloc(sizeof(DEVMODE)*num_modes);
  297.     num_modes = 0;
  298.     while (EnumDisplaySettings(NULL, num_modes, &devmodes[num_modes]))
  299.     num_modes++;
  300.  
  301.     while(GetMessage(&msg, hWnd, 0, 0)) {
  302.     TranslateMessage(&msg);
  303.     DispatchMessage(&msg);
  304.     }
  305.  
  306.     /* free the array of devmodes, and click our heels to come back
  307.        from Oz...don't forget Toto. */
  308.     free(devmodes);
  309.     ChangeDisplaySettings(NULL, 0);
  310.  
  311.     wglMakeCurrent(NULL, NULL);
  312.     ReleaseDC(hDC, hWnd);
  313.     wglDeleteContext(hRC);
  314.     DestroyWindow(hWnd);
  315.  
  316.     return msg.wParam;
  317. }
  318. 
  319.